package aviso.controller;

import aviso.entity.ScheduledMailRecord;
import aviso.entity.UserName;
import aviso.entity.util.JsfUtil;
import aviso.entity.util.LocaleService;
import aviso.entity.util.PasswordUtil;
import aviso.facade.ScheduledMailRecordFacade;
import aviso.facade.UserNameFacade;
import aviso.managedbeans.GroupNameBean;
import java.io.Serializable;
import java.util.Calendar;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.validation.constraints.Pattern;

@ManagedBean
@ViewScoped
public class ProfileController implements Serializable {

    //private UserName current=new UserName();
    @EJB
    private aviso.facade.UserNameFacade userNameFacade;
    @EJB
    private ScheduledMailRecordFacade mailRecordFacade;
    @ManagedProperty(value = "#{frontController}")
    private FrontController fc;
    @ManagedProperty(value = "#{groupNameBean}")
    private GroupNameBean groupNameBean;
    private boolean oldPasswordValid = false;
    private String password = "";
    private String password2 = "";
    private String oldpassword = "";
    private boolean changePassword;
    @Pattern(regexp = "^([0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$", message = "{invalidEmailResourceBundleKey}")
    private String email = "";

    public ProfileController() {
    }

    public FrontController getFc() {
        return fc;
    }

    public void setFc(FrontController fc) {
        this.fc = fc;
    }

    public GroupNameBean getGroupNameBean() {
        return groupNameBean;
    }

    public void setGroupNameBean(GroupNameBean groupNameBean) {
        this.groupNameBean = groupNameBean;
    }

    public UserName getCurrent() {
        return fc.getUser();
    }

    public void setCurrent(UserName current) {
        //this.current = current;
    }

    private UserNameFacade getFacade() {
        return userNameFacade;
    }

    public String saveInProfile() {
        if (save()) {
            return "index";
        }
        return "";
    }

    public boolean save() {
        UserName current = fc.getUser();
        if (getPassword().length() > 0) {
            if (!getPassword().equals(getPassword2())) {
                JsfUtil.addErrorMessage("userform:pass", LocaleService.getTranslation("Passwordsdontmatch"));
                JsfUtil.addErrorMessage("userform:pass2", LocaleService.getTranslation("Passwordsdontmatch"));
                return false;
            }
        }
        if (fc.islogedIn() && !isOldPasswordValid()) {
            JsfUtil.addErrorMessage("userform:oldpass", LocaleService.getTranslation("PasswordDotMatch"));
            return false;
        }
        //TODO potential security hole - password can be updated without confirmation
        if (getPassword().length() > 0) {
            current.setPasshash(PasswordUtil.genPassHash(getPassword()));
        }
        if (current.getCreated() == null) {
            current.setCreated(Calendar.getInstance());
        }
        if (current.getGroup() == null) {
            current.setGroup(groupNameBean.getUser());
        }
        if (!email.equals(current.getEmail())) {
            current.setEmail(email);
            current.setEmailHash((email.hashCode() + (int) Math.random() * 100000) + "");
        }
        try {
            if (current.getId() == null) {
                create(current);
            } else {
                update(current);
                fc.setUser(current);
            }
            if (current.getEmailHash().length() > 0) {
                createEmailValidationEmail(current);
            }

            return true;
        } catch (Exception e) {
            return false;
        }

    }

    public void create(UserName current) {
        try {

            if (!getFacade().isNameExist(current.getName())) {
                getFacade().create(current);
                JsfUtil.addSuccessMessage(LocaleService.getTranslation("UserNameCreated"));

            } else {
                JsfUtil.addSuccessMessage(LocaleService.getTranslation("UserNameAlreadyExist"));

            }
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, LocaleService.getTranslation("PersistenceErrorOccured"));

        }
    }

    public void update(UserName current) {
        try {
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(LocaleService.getTranslation("UserNameUpdated"));

        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, LocaleService.getTranslation("PersistenceErrorOccured"));

        }
    }

    public String getEmail() {
        if (email.length() == 0 && fc.getUserID() != 0) {
            email = fc.getUser().getEmail();
        }
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getOldpassword() {
        return oldpassword;
    }

    public void setOldpassword(String oldpassword) {
        this.oldpassword = oldpassword;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }

    public boolean isOldPasswordValid() {
        if (!fc.islogedIn()) {
            return true;
        }
        return oldPasswordValid;
    }

    public void setOldPasswordValid(boolean oldPasswordValid) {
        this.oldPasswordValid = oldPasswordValid;
    }

    public boolean isChangePassword() {
        return changePassword;
    }

    public void setChangePassword(boolean changePassword) {
        this.changePassword = changePassword;
    }

    public void prepareToChangePassword() {
        changePassword = !changePassword;
    }

    public void validateEmail(FacesContext context, UIComponent toValidate, Object value) {
        String email = (String) value;
        if (email == null || email.trim().length() < 1) {
            ((UIInput) toValidate).setValid(false);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, LocaleService.getTranslation("Invalid email"),
                    LocaleService.getTranslation("Invalidemail"));
            context.addMessage(toValidate.getClientId(context), message);
        } else {
            ((UIInput) toValidate).setValid(true);
        }
    }

    public void validateOldPassword(FacesContext context, UIComponent toValidate, Object value) {
        String oldpass = (String) value;
        if (oldpass.length() == 0) {
            setOldPasswordValid(false);
            ((UIInput) toValidate).setValid(true);
            return;
        }
        if (!fc.getUser().getPasshash().equals(PasswordUtil.genPassHash(oldpass))) {
            setOldPasswordValid(false);
            ((UIInput) toValidate).setValid(false);
            JsfUtil.addErrorMessage(toValidate.getClientId(context), LocaleService.getTranslation("PasswordIncorrect"));
        } else {
            setOldPasswordValid(true);
            ((UIInput) toValidate).setValid(true);
        }
    }

    public void validateUserName(FacesContext context, UIComponent toValidate, Object value) {
        String name = (String) value;
        if (userNameFacade.isNameExist(name)) {
            ((UIInput) toValidate).setValid(false);
            JsfUtil.addErrorMessage(toValidate.getClientId(context), LocaleService.getTranslation("UserNameAlreadyExists"));
        } else {

            ((UIInput) toValidate).setValid(true);
        }
    }

    public void validatePasswordSize(FacesContext context, UIComponent toValidate, Object value) {
        String pass = (String) value;
        if (isChangePassword()) {
            if (!(pass.length() >= 5 && pass.length() <= 10 && isOldPasswordValid())) {
                ((UIInput) toValidate).setValid(false);
                JsfUtil.addErrorMessage(toValidate.getClientId(context), LocaleService.getTranslation("PassworSizeIncorrect"));
                return;
            }
        }
        ((UIInput) toValidate).setValid(true);
    }

    public void emailHashVerify(ValueChangeEvent e) {
        UserName tmp = userNameFacade.verifyEmail(e.getNewValue());
        if (tmp != null) {
            fc.setUser(tmp);
            fc.setUser(tmp);
            fc.logIn();
            JsfUtil.addSuccessMessage(LocaleService.getTranslation("EmailVerified"));
        } else {
            JsfUtil.addErrorMessage(LocaleService.getTranslation("EmailVerificationFailed"));
        }

    }
  
    private void createEmailValidationEmail(UserName current) {
        ScheduledMailRecord mailRecord = new ScheduledMailRecord();
        mailRecord.setMessageTo(current.getEmail());
        mailRecord.setMessageBody("validate code=" + current.getEmailHash());
        mailRecordFacade.create(mailRecord);

    }
}
